package demo.java.text;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 数字格式化
 *
 * @author hanjy
 */
public class NumberFormatDemo {

    private static Logger logger = LoggerFactory.getLogger(NumberFormatDemo.class);

    public static Random random = new Random();

    @Test
    public void decimalFormatDemo() {
        System.out.println(format("###,###.###", 123456.789));
        System.out.println(format("###.##", 123456.789));
        System.out.println(format("000000.000", 123.78));
        System.out.println(format("$###,###.###", 12345.67));
    }

    /**
     * <li>#.00表示保留后两位
     *
     * @param pattern
     * @param value
     */
    public static String format(String pattern, double value) {
        DecimalFormat myFormatter = new DecimalFormat(pattern);
        return myFormatter.format(value);
    }

    /**
     * 百分比格式化
     */
    @Test
    public void percentFormat() {
        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(2);
        logger.info("原始值：{},百分比格式化后：{}", Math.E, numberFormat.format(Math.E));
        logger.info("原始值：{},百分比格式化后：{}", Math.PI, numberFormat.format(Math.PI));
        logger.info("原始值：{},百分比格式化后：{}", Integer.MAX_VALUE, numberFormat.format(Integer.MAX_VALUE));
    }

    /**
     * DecimalFormat默认采用了RoundingMode.HALF_EVEN这种类型,而且format之后的结果是一个字符串类型String
     */
    @Test
    public void demo2() {
        String format = "#0.000";
        System.out.println("============" + format);
        random.doubles(20).forEach(d -> {
            System.out.println(d + "=>" + format(format, d));
        });

        String format2 = "#.###";
        System.out.println("============" + format2);
        random.doubles(20).forEach(d -> {
            System.out.println(d + "=>" + format(format2, d));
        });

        String format3 = "#0.000";
        System.out.println("============" + format3);
        random.doubles(20).forEach(d -> {
            System.out.println(d * 10000 + "=>" + format(format3, d * 10000));
        });
        String format4 = "#0.000";
        System.out.println("============" + format4);
        random.ints(20).forEach(d -> {
            System.out.println(d * 10000 + "=>" + format(format3, d * 10000));
        });

        random.doubles(20).forEach(d -> {
            System.out.println(d + "=>" + String.format("%010f", d));
        });
    }

    @Test
    public void demo3() {
        random.ints(20).forEach(d -> {
            System.out.println(d + " = " + scale(3, (double) d));
        });
        System.out.println("============");
        random.doubles(20).forEach(d -> {
            System.out.println(d * 1000 + " = " + scale(3, d * 1000));
        });
        System.out.println("============");
        random.doubles(20).forEach(d -> {
            System.out.println(d + " = " + format(3, d));
        });
    }

    /**
     * 保留n位数字，不够补0
     *
     * @param newScale
     * @param value
     * @return
     */
    public static String scale(int newScale, double value) {
        if (newScale < 1) {
            throw new IllegalArgumentException("param 'newScale' need bigger than 0");
        }
        String str = IntStream.range(0, newScale).mapToObj(e -> "0").collect(Collectors.joining(""));
        String str2 = BigDecimal.valueOf(value).toPlainString() + str;
        System.out.println(str2);
        int index = str2.indexOf(".");
        return str2.substring(0, index + newScale + 1);
    }

    @Test
    public void testPi() {
        System.out.println("PI = " + Math.PI);
        System.out.println("保留两位有效数字 = " + String.format("%.2f", Math.PI));
        System.out.println("百分比 = " + String.format("%.2f%%[]", Math.PI * 100));
        System.out.println("固定长度，不足填充零 = " + format("000.000", Math.PI));
        System.out.println("百分比 = " + format("0.00%", Math.PI));
    }

    /**
     * @param maximumFractionDigits
     * @param value
     */
    public static String format(int maximumFractionDigits, double value) {
        NumberFormat nf = NumberFormat.getNumberInstance();
        // 保留N位小数
        nf.setMaximumFractionDigits(maximumFractionDigits);
        // 如果不需要四舍五入，可以使用RoundingMode.DOWN
        nf.setRoundingMode(RoundingMode.DOWN);
        return nf.format(value);
    }

}
